﻿/** 
 *@Name：DataType 扩展
 *@Author：Yongjin.C 995292291@qq.com
 */
!function(window, undefined) {
    var _YJ = {};
    var reInt = /^\s*[+-]?\d+\s*$/; //整数类型
    var reUInt = /^\s*[+]?\d+\s*$/; //正整数类型
    _YJ.DataType = {
        Number: {
            Name: "Number",
            CheckRange: function(val) {
                return !isNaN(val);
            },
            roundTo: function(val, precision) {
                /// <summary>
                /// 将小数转换为固定小数位的形式
                /// </summary>
                /// <param name="val" type='Number'>小数</param>
                /// <param name="precision" type='Number'>保留几位小数</param>
                /// <returns type="Number"></returns>
                var m = Math.pow(10, precision);
                var a = Math.round(val * m) / m;
                return a;
            },
            randomBetween: function(min, max) {
                return min + Math.floor(Math.random() * (max - min + 1));
            }
        },
        Int16: { Name: "Int16", MaxValue: 32767, MinValue: -32768, CheckRange: function(val) { return ((isFinite(val)) && (reInt.test(val)) && (this.MaxValue >= val) && (this.MinValue <= val)) } },
        Int32: { Name: "Int32", MaxValue: 2147483647, MinValue: -2147483648, CheckRange: function(val) { return ((isFinite(val)) && (reInt.test(val)) && (this.MaxValue >= val) && (this.MinValue <= val)) } },
        Int64: { Name: "Int64", MaxValue: 9223372036854776000, MinValue: -9223372036854776000, CheckRange: function(val) { return ((isFinite(val)) && (reInt.test(val)) && (this.MaxValue >= val) && (this.MinValue <= val)) } },
        Float: { Name: "Float", MaxValue: 3.402823e+38, MinValue: -3.402823e+38, CheckRange: function(val) { return ((isFinite(val)) && (this.MaxValue >= val) && (this.MinValue <= val)) } },
        Double: { Name: "Double", MaxValue: 1.79e+308, MinValue: -1.79e+308, CheckRange: function(val) { return ((isFinite(val)) && (this.MaxValue >= val) && (this.MinValue <= val)) } },
        UInt16: { Name: "UInt16", MaxValue: 65535, MinValue: 1, CheckRange: function(val) { return ((isFinite(val)) && (reUInt.test(val)) && (this.MaxValue >= val) && (this.MinValue <= val)) } },
        UInt32: { Name: "UInt32", MaxValue: 4294967295, MinValue: 1, CheckRange: function(val) { return ((isFinite(val)) && (reUInt.test(val)) && (this.MaxValue >= val) && (this.MinValue <= val)) } },
        UInt64: { Name: "UInt64", MaxValue: 18446744073709552000, MinValue: 1, CheckRange: function(val) { return ((isFinite(val)) && (reUInt.test(val)) && (this.MaxValue >= val) && (this.MinValue <= val)) } },
        UFloat: { Name: "UFloat", MaxValue: 3.402823E+38, MinValue: 0, CheckRange: function(val) { return ((isFinite(val)) && (this.MaxValue >= val) && (this.MinValue <= val)); } },
        UDouble: { Name: "Double", MaxValue: 1.79e+308, MinValue: 0, CheckRange: function(val) { return ((isFinite(val)) && (this.MaxValue >= val) && (this.MinValue <= val)) } },
        DateTime: {
            Name: "DateTime",
            MaxValue: new Date(9999, 12, 31, 23, 59, 59),
            MinValue: new Date(1, 1, 1, 0, 0, 0),
            CheckRange: function(val) {
                var temp = Date.parse(val);
                return ((!isNaN(temp)) && (this.MaxValue >= temp) && (this.MinValue <= temp))
            }
        },
        String: {
            Name: "String",
            IsNullOrEmpty: function(val) { return !val; },
            IsNullOrWhiteSpace: function(val) { return (val == null) || /^\s*$/.test(val); },
            _charToDouble_byte: function(txtstring) {
                /// <summary>
                ///  全角空格为12288，半角空格为32
                ///其他字符半角(33-126)与全角(65281-65374)的对应关系是：均相差65248
                ///半角转换为全角函数
                /// </summary>
                /// <param name="txtstring"></param>
                /// <returns type=""></returns>
                var tmp = "";
                for (var i = 0; i < txtstring.length; i++) {
                    if (txtstring.charCodeAt(i) == 32) {
                        tmp = tmp + String.fromCharCode(12288);
                    }
                    if (txtstring.charCodeAt(i) < 127) {
                        tmp = tmp + String.fromCharCode(txtstring.charCodeAt(i) + 65248);
                    }
                }
                return tmp;
            },

            _charToHalf_width: function(str) {
                /// <summary>
                ///  全角转换为半角函数
                /// </summary>
                /// <param name="str"></param>
                /// <returns type=""></returns>
                var tmp = "";
                for (var i = 0; i < str.length; i++) {
                    if (str.charCodeAt(i) > 65248 && str.charCodeAt(i) < 65375) {
                        tmp += String.fromCharCode(str.charCodeAt(i) - 65248);
                    } else {
                        tmp += String.fromCharCode(str.charCodeAt(i));
                    }
                }
                return tmp;
            },
            Trim: function(val, rep) {
                if (!!val) {
                    if (!!rep) {
                        rep = rep.replace(/\\/g, "\\\\").replace(/\//g, "\/");
                        var reg = new RegExp("(^" + rep + ")|(" + rep + "$)", "g");
                        return val.replace(reg, "");
                    }
                    return val.replace(/(^(\s*|　*))|((\s*|　*)$)/g, "");
                }
                return val;
            },
            RTrim: function(val, rep) {
                if (!!val) {
                    if (!!rep) {
                        rep = rep.replace(/\\/g, "\\\\").replace(/\//g, "\/");
                        var reg = new RegExp("(" + rep + "$)", "g");
                        return val.replace(reg, "");
                    }
                    return val.replace(/(\s*|　*)$/g, "");
                }
                return val;
            },
            LTrim: function(val, rep) { //删除左边的空格
                if (!!val) {
                    if (!!rep) {
                        rep = rep.replace(/\\/g, "\\\\").replace(/\//g, "\/");
                        var reg = new RegExp("(^" + rep + ")", "g");
                        return val.replace(reg, "");
                    }
                    return val.replace(/^(\s*|　*)/g, "");
                }
                return val;
            },
            // 返回字符串的实际长度, 一个汉字算2个长度
            Length: function(val) { return val.replace(/[^\x00-\xff]/g, "**").length; },
            subStr: function(str, size, suffix) { //支持汉字
                if (!str || this.Length(str) <= size) {
                    return str;
                }
                var l = 0;
                var lStr = "";
                for (var i = 0; i < str.length; i++) {
                    l += this.Length(str.charAt(i));
                    if (l >= size) {
                        lStr = str.substring(0, i + 1);
                        break;
                    }
                }
                if (!!suffix)
                    lStr += suffix;
                return lStr;
            },
            coverToUnicode: function(str, cssType) {
                var i = 0,
                    l = str.length,
                    result = [], //转换后的结果数组
                    unicodePrefix //unicode前缀 (example:\1234||\u1234)

                        //如果是css中使用格式为\1234之类
                        //字符串的charCodeAt方法返回的是10进制的unicode，所以我们需要用toString(16)将其转为16进制的，才能在JS及CSS中使用，而CSS中跟JS不同的是少了个U
                        = (cssType && cssType.toLowerCase() === 'css') ? '\\' : '\\u';

                for (; i < l; i++) {
                    var cr = str.charCodeAt(i);
                    if (cr > 255) {
                        result.push(unicodePrefix + cr.toString(16));
                    } else
                        result.push(str.charAt(i));
                }

                return result.join('');
            }
        },
        URL: {
            Name: "URL",
            CheckRange: function(val) {
                var strRegex = "^((https|http|ftp|rtsp|mms)?://)"
                    + "?(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?" //ftp的user@ 
                    + "(([0-9]{1,3}\.){3}[0-9]{1,3}" // IP形式的URL- 199.194.52.184   
                    + "|" // 允许IP和DOMAIN（域名） 
                    + "([0-9a-z_!~*'()-]+\.)*" // 域名- www.  
                    + "([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\." // 二级域名 
                    + "[a-z]{2,6})" // first level domain- .com or .museum  
                    + "(:[0-9]{1,4})?" // 端口- :80  
                    + "((/?)|" // a slash isn't required if there is no file name 
                    + "(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$";
                var re = new RegExp(strRegex);
                return !!re.test(val);
            }
        },
        Email: {
            Name: 'Email',
            CheckRange: function(val) {
                var f = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/.test(val);
                return !!f;
            }
        },
        ZHpostcode: {
            Name: 'ZHpostcode',
            CheckRange: function(val) {
                return !!(/^[1-9]\d{5}(?!\d)$/.test(val));
            }
        },
        ZHtel: {
            Name: 'ZHtel',
            CheckRange: function(val) {
                return !!(/^((\d{3}-\d{8}|\d{4}-\d{7}))(-\d{1,4}){0,1}$/g.test(val));
            }
        },
        ZHIDCard: {
            Name: 'ZHIDCard',
            CheckRange: function(val) {
                //身份证正则表达式(15位) 
                var isIDCard1 = /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$/;
                //身份证正则表达式(18位)
                var isIDCard2 = /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$/;
                //验证身份证，返回结果 
                return (!!isIDCard1.test(val) || !!isIDCard2.test(val));
            },
            CheckStrict: function(number) {
                var area = {
                    11: "北京",
                    12: "天津",
                    13: "河北",
                    14: "山西",
                    15: "内蒙古",
                    21: "辽宁",
                    22: "吉林",
                    23: "黑龙江",
                    31: "上海",
                    32: "江苏",
                    33: "浙江",
                    34: "安徽",
                    35: "福建",
                    36: "江西",
                    37: "山东",
                    41: "河南",
                    42: "湖北",
                    43: "湖南",
                    44: "广东",
                    45: "广西",
                    46: "海南",
                    50: "重庆",
                    51: "四川",
                    52: "贵州",
                    53: "云南",
                    54: "西藏",
                    61: "陕西",
                    62: "甘肃",
                    63: "青海",
                    64: "宁夏",
                    65: "新疆",
                    71: "台湾",
                    81: "香港",
                    82: "澳门",
                    91: "国外"
                };
                var idcard, Y, JYM;
                var S, M;
                var idcard_array = new Array();
                idcard_array = number.split("");
                //地区检验
                if (area[parseInt(number.substr(0, 2))] == null) return false;
                //身份号码位数及格式检验
                switch (number.length) {
                case 15:
                    if ((parseInt(number.substr(6, 2)) + 1900) % 4 == 0 || ((parseInt(number.substr(6, 2)) + 1900) % 100 == 0
                        && (parseInt(number.substr(6, 2)) + 1900) % 4 == 0)) {
                        //测试出生日期的合法性
                        ereg = /^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}$/;
                    } else {
                        //测试出生日期的合法性
                        ereg = /^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}$/;
                    }
                    if (ereg.test(number)) {
                        return true;
                    } else {
                        return false;
                    }
                    break;
                case 18:
                    /*18位身份号码检测
                                        出生日期的合法性检查
                                        闰年月:
                                        ((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))
                                        平年月日:
                                        ((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))*/
                    if (parseInt(number.substr(6, 4)) % 4 == 0 || (parseInt(number.substr(6, 4)) % 100 == 0
                        && parseInt(number.substr(6, 4)) % 4 == 0)) {
                        //闰年出生日期的合法性正则表达式
                        ereg = /^[1-9][0-9]{5}(19|20)[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9Xx]$/;
                    } else {
                        //平年出生日期的合法性正则表达式
                        ereg = /^[1-9][0-9]{5}(19|20)[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}[0-9Xx]$/;
                    }
                    //测试出生日期的合法性
                    if (ereg.test(number)) {
                        //计算校验位
                        S = (parseInt(idcard_array[0]) + parseInt(idcard_array[10])) * 7 + (parseInt(idcard_array[1])
                                + parseInt(idcard_array[11])) * 9 + (parseInt(idcard_array[2]) + parseInt(idcard_array[12])) * 10
                            + (parseInt(idcard_array[3]) + parseInt(idcard_array[13])) * 5 + (parseInt(idcard_array[4])
                                + parseInt(idcard_array[14])) * 8 + (parseInt(idcard_array[5]) + parseInt(idcard_array[15])) * 4
                            + (parseInt(idcard_array[6]) + parseInt(idcard_array[16])) * 2 + parseInt(idcard_array[7]) * 1
                            + parseInt(idcard_array[8]) * 6 + parseInt(idcard_array[9]) * 3;
                        Y = S % 11;
                        M = "F";
                        JYM = "10X98765432";
                        M = JYM.substr(Y, 1); //判断校验位
                        if (M == idcard_array[17]) return true; //检测ID的校验位
                        else return false;
                    } else return false;
                    break;
                default:
                    return false;
                    break;
                }
            }
        }
    };
    //取得控件得绝对位置
    _YJ.getoffset = function(node) {
        var t = node.offsetTop, l = node.offsetLeft;
        while (node = node.offsetParent) {
            t += node.offsetTop;
            l += node.offsetLeft;
            //x += -e.scrollLeft + e.offsetLeft //+ e.clientLeft;
            //y += -e.scrollTop + e.offsetTop // + e.clientTop;
        }
        return { left: l, top: t }
    }
    _YJ.getQueryString = function(name) {
        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
        var r = window.location.search.substr(1).match(reg);
        return r != null ? unescape(r[2]) : null;
    }
    window.YJTool = _YJ;
    window.String.prototype.replaceAll = function(s1, s2) {
        return this.replace(new RegExp(s1, "gm"), s2);
    }
    window.String.prototype.startWith = function(s) {
        return this.indexOf(s) == 0;
    }
    window.String.prototype.endWith = function(s) {
        var d = this.length - s.length;
        return (d >= 0 && this.lastIndexOf(s) == d);
    }
    if (!window.String.prototype.format) {
        window.String.prototype.format = function() {
            var obj = typeof arguments[0] === "object" ? arguments[0] : arguments;
            return arguments.length > 0 ? this.replace(/{(\w+)}/g, function($0, $1) { //match
                return typeof obj[$1] != 'undefined'
                    ? obj[$1]
                    : $0;
            }) : this;
        };
    }
    //#region 元素扩展on和triger
    window.Element.prototype.on = Element.prototype.addEventListener || element.attachEvent;
    window.NodeList.prototype.on = function(event, fn) {
        []['forEach'].call(this, function(el) {
            el.on(event, fn);
        });
        return this;
    };
    window.Element.prototype.trigger = function(type, data) {
        var event = document.createEvent('HTMLEvents');
        event.initEvent(type, true, true);
        event.data = data || {};
        event.eventName = type;
        event.target = this;
        this.dispatchEvent(event);
        return this;
    };
    window.NodeList.prototype.trigger = function(event) {
        []['forEach'].call(this, function(el) {
            el['trigger'](event);
        });
        return this;
    };
    //#endregion
}(window, undefined);